import React from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import Dom from '../utils/Dom';
import Dropdown from './Dropdown';
import Icon from '../Icon';

import './Cascader.less';

class Cascader extends React.Component {
    displayName = 'Cascader';

    static defaultProps= {
        align : 'bottomLeft',
        trigger: 'click',
        valueField: 'id',
        textField: 'text',
        transfer: false,
        sep: '/'
    }

    state = {
        open: false,
        current: []
    }

    onShowHide = (e) => {
        const {disabled, value, sep} = this.props;
        const ele = e.target || e.srcElement;
        // click clear icon
        if (ele.tagName === 'I' && ele.className.indexOf('cm-select-clear') !== -1) {
            return;
        }
        if (disabled) {
            return;
        }
        let current;
        if (value) {
            current = value.split(sep);
        } else {
            current = [];
        }
        const open = this.state.open;
        this.setState({
            current,
            open: !open
        });
    }

    componentDidMount () {
        this._isMounted = true;
        if (this.props.trigger === 'click' && !this.props.inner) {
            document.addEventListener('click', this.clickAnyWhere.bind(this), false);
        }
    }

    componentWillUnmount () {
        this._isMounted = false;
        if (this.props.trigger === 'click' && !this.props.inner) {
            document.removeEventListener('click', this.clickAnyWhere);
        }
    }

    clickAnyWhere (e) {
        const ele = e.target || e.srcElement;
        const parent = Dom.closest(ele, '.cm-cascader');
        if (parent && parent == this.wrap) {
            return ;
        } else {
            this._isMounted && this.setState({
                open: false
            });
        }
    }

    getMap (map, data) {
        const {textField, valueField} = this.props;
        data && data.forEach(item => {
            if (item.children && item.children instanceof Array) {
                this.getMap(map, item.children);
            }
            map[item[valueField]] = item[textField];
        });
    }

    renderText () {
        const {value, data, sep} = this.props;
        const arr = value ? value.split(sep) : [];
        const map = {};
        this.getMap(map, data);

        const text = arr && arr.map(item => {
            return map[item];
        }).join(` ${sep} `);
        return <div className='cm-select-text' >{text}</div>;
    }

    onSelectItem = async (item, level, isLeaf) => {
        const current = this.state.current;
        if (`${item[this.props.valueField]}` !== current[level]) {
            current[level] = item[this.props.valueField];
            if (current.length > level + 1) {
                current.length = level + 1;
            }
        }
        let shouldClose = isLeaf;
        if (item.danymicData && typeof item.danymicData === 'function') {
            item.loading = true;
            shouldClose = false;
        }
        this._isMounted && this.setState({
            current
        }, async () => {
            if (item.danymicData && typeof item.danymicData === 'function') {
                // eslint-disable-next-line require-atomic-updates
                item.children = await item.danymicData();
                // eslint-disable-next-line require-atomic-updates
                item.loading = false;
                // eslint-disable-next-line require-atomic-updates
                item.danymicData = false;
            }
            if (this.props.changeOnSelect) {
                this.props.onChange && this.props.onChange(current.join(this.props.sep));
            } else {
                this._isMounted && this.setState({
                    current
                });
            }
        });
        if (shouldClose) {
            this._isMounted && this.setState({
                open: false
            }, () => {
                this.props.onChange && this.props.onChange(current.join(this.props.sep));
            });
        }
    }

    /**
     * 清除
     */
    onClear = () => {
        if (this.props.onClear) {
            this.props.onClear();
        }
        if (this.props.onChange) {
            this.props.onChange('');
        }
    }

    render () {
        const {className, style, transfer, name, value, prefix, data, valueField, textField, size, disabled, clearable} = this.props;
        const clazzName = classNames('cm-cascader', className, {
            'cm-cascader-open': this.state.open,
            'cm-cascader-transfer': transfer,
            'cm-cascader-disabled': disabled,
            'cm-cascader-clearable': !disabled && clearable && value && value.length,
            [`cm-cascader-${size}`]: size
        });
        return <div className={clazzName} style={style}  ref={f => this.wrap = f}>
            <div className='cm-select-value' tabIndex='0' onClick={this.onShowHide}>
                <input type='hidden' name={name} value={value}/>
                {
                    prefix
                        ? <span className='cm-select-prefix'>{prefix}</span>
                        : null
                }
                {this.renderText()}
                <Icon name='ios-arrow-down' className='cm-select-cert'/>
                {
                    clearable
                        ? <Icon name='ios-close-circle' className='cm-select-clear' onClick={this.onClear}/>
                        : null
                }
            </div>
            <div className='cm-cascader-options-wrap'>
                <Dropdown active={this.state.current} data={data} trigger='click' onSelect={this.onSelectItem} valueField={valueField} textField={textField}></Dropdown>
            </div>
        </div>;
    }
}

export default Cascader;
